package com.gh;

import java.io.IOException;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Spinner;

public class GHSteeringWheelActivity extends Activity {

	private static final String TAG = "FRANKLIN";
	
	// constants
	public static final String DEBUG_SERVER_LOC = "http://webster.cs.washington.edu/params.php";
	public static final String SERVER_LOC = "http://50.112.52.104/ghang/updates/update.php";

	// fields for GC help
	private HttpClient hc;
	private HttpGet get;
	private HttpResponse rp;
	private ProgressBar pb;
	private Button accelButton;
	private Button toggleButton;
	private Spinner playerIdSpinner;

	// sensor vars
	private SensorManager sensorManager;
	private Sensor sensor;
	private float x, y, z;
	private boolean doSendData;
	private boolean isAccelerating;
	
	// Time variables
	private long timeStamp;
	private Date curDate;
	private static final int FREQUENCY = 1000; // # of milliseconds between each accelerometer read

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		hc = new DefaultHttpClient();

		sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
		sensor = sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0);
		sensorManager.registerListener(accelerationListener, sensor,
				SensorManager.SENSOR_DELAY_UI);
		doSendData = false;
		isAccelerating = false;
		
		curDate = new Date();
		timeStamp = curDate.getTime();
		
		pb = ((ProgressBar) findViewById(R.id.leftRightGauge));
		
		playerIdSpinner = (Spinner)findViewById(R.id.player_id_spinner);
		ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.player_id_array, android.R.layout.simple_spinner_item);
		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		playerIdSpinner.setAdapter(adapter);
		
		toggleButton = (Button)findViewById(R.id.toggle_accel);
		toggleButton.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				doSendData = !doSendData;
				if (!doSendData) {
					pb.setProgress(0);
				}
			}
		});
		
		accelButton = (Button) findViewById(R.id.accelButton);
		accelButton.setOnTouchListener(new OnTouchListener() {
			
			public boolean onTouch(View v, MotionEvent event) {
				if (event.getAction() == MotionEvent.ACTION_DOWN) {
					Log.e(TAG, "action down");
					accelButton.setText("Accelerating");
					isAccelerating = true;
				} else if (event.getAction() == MotionEvent.ACTION_UP) {
					Log.e(TAG, "action up");
					accelButton.setText("Not accelerating");
					isAccelerating = false;
				}
				return true;
				
			}
		});
	}

	private void sendMove(int move) {
		try {
//			params = new BasicHttpParams();
//			params.setParameter("u", "id1");
//			params.setIntParameter("d", move);
//			get.setParams(params);
			get = new HttpGet(SERVER_LOC + "?u=id1&d=" + move);
			rp = hc.execute(get);
			
			if (rp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
//				Log.d("RETURN_VALUE", "sent: " + EntityUtils.toString(rp.getEntity()));
				rp.getEntity().consumeContent();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private SensorEventListener accelerationListener = new SensorEventListener() {

		public void onAccuracyChanged(Sensor sensor, int acc) {
		}

		public void onSensorChanged(SensorEvent event) {
			if (doSendData) {
				curDate = new Date();
	//			x = event.values[0];
				y = event.values[1];
	//			z = event.values[2];
				pb.setProgress(((int)y) + 10);
				Log.d("ACCEL", "x:" + x + " y:" + y + " z:" + z);
				
				// u --> user_id {0,1,2}
			       // d --> direction [0,20]
			       // a --> acceleration [0,1]
				
				if (curDate.getTime() > timeStamp + FREQUENCY) {
	//				Log.d("ACCEL", ""+y);
					timeStamp = curDate.getTime();
	//				sendMove(Math.round(y));
					int accelerate = isAccelerating ? 1: 0;
					new SendAccelerometerTask().execute("u", String.valueOf(playerIdSpinner.getSelectedItemPosition()),
							"d", String.valueOf(y), "a", String.valueOf(accelerate));
				}
			}
		}

	};
	
	protected void onPause() {
		super.onPause();
		this.finish();
	}

	@Override
	protected void onResume() {
		super.onResume();
		sensorManager.registerListener(accelerationListener, sensor,
				SensorManager.SENSOR_DELAY_GAME);
	}

	@Override
	protected void onStop() {
		sensorManager.unregisterListener(accelerationListener);
		super.onStop();
	}
	
	private class SendAccelerometerTask extends AsyncTask<String, Void, Void> {

		@Override
		protected Void doInBackground(String... query) {
			if (query.length != 6) {
				Log.e(TAG, "wrong number of query params");
				return null;
			}
			try {
				HttpClient h = new DefaultHttpClient();
				List<NameValuePair> paramList = new LinkedList<NameValuePair>();
				paramList.add(new BasicNameValuePair(query[0], query[1]));
				paramList.add(new BasicNameValuePair(query[2], query[3]));
				paramList.add(new BasicNameValuePair(query[4], query[5]));
				String paramString = URLEncodedUtils.format(paramList, "utf-8");
				Log.e(TAG, "paramString = " + paramString);
				HttpGet g = new HttpGet(SERVER_LOC + "?" + paramString);
				HttpResponse r = h.execute(g);
//				if (r.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
//					Log.e("RETURN_VALUE", "sent: " + EntityUtils.toString(r.getEntity()));
//					r.getEntity().consumeContent();
//				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			return null;
		}
		
	}
	
}